﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class SetTargetForm : Form
    {
        public delegate void save_delegate(Image img,params Rectangle[] rectangles);
        public event save_delegate SAVE_EVENT;


        //记录rect信息
        Rectangle[] rectArray = new Rectangle[10];
        Rectangle rect = new Rectangle();
        Point start_p, end_p;
        bool isSettingRect_1 = false, isSettingRect_2 = false;
        bool isRectDrawing = false;
        //记录图片尺寸
        Size picSize = new Size(0, 0);

        //记录设置窗口加载的图像对象
        Image img;
        public SetTargetForm()
        {
            InitializeComponent();
        }

        private void load_bt_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "jpg|*.jpg|jpeg|*.jpeg|bmp|*.bmp";
            openFileDialog.FilterIndex = 1;
            openFileDialog.RestoreDirectory = true;
            if(!(openFileDialog.ShowDialog() == DialogResult.OK))
            {
                return;
            }

            textBox1.Text = openFileDialog.FileName;
            img = Image.FromStream(openFileDialog.OpenFile());

            if(img!=null)
            {
                setTargetArea_bt.Enabled = true;
                setTarget2Area_bt.Enabled = true;
                setTarget_pb.Invoke(new Action(() =>
                {
                    setTarget_pb.Image = img;
                }));
                picSize = img.Size;
            }
        }


        private void setTarget_pb_MouseDown(object sender, MouseEventArgs e)
        {
            isRectDrawing = true;
            start_p = e.Location;
            rect.Location = start_p;
        }

        private void setTarget_pb_MouseMove(object sender, MouseEventArgs e)
        {
            #region 显示当前鼠标坐标
            x_posit.Invoke(new Action(() => {
                x_posit.Text = e.Location.X.ToString();
            }));
            y_posit.Invoke(new Action(() => {
                y_posit.Text = e.Location.Y.ToString();
            }));
            #endregion
            bool isSettintRect = isSettingRect_1 | isSettingRect_2;
            if (isSettintRect & isRectDrawing)
            {
                end_p = e.Location;
                rect.Width = end_p.X - start_p.X;
                rect.Height = end_p.Y - start_p.Y;
                setTarget_pb.Invalidate();
            }
        }

        private void setTarget_pb_MouseUp(object sender, MouseEventArgs e)
        {
            if(isRectDrawing)
            {
                isRectDrawing = false;

                Rectangle r1,r2;
                deepCopy(in rect, out r1);
                Point pStart, pEnd;
                Point pStart_out, pEnd_out;
                pStart = r1.Location;
                pEnd = new Point(r1.X+r1.Width,r1.Y+r1.Height);
                Size panelSize, picSize;
                panelSize = setTarget_pb.Size;
                picSize = this.picSize;
                transPositToPic(in pStart, panelSize, picSize, out pStart_out);
                transPositToPic(in pEnd, panelSize, picSize, out pEnd_out);
                Rectangle rect_pic = new Rectangle(pStart_out,new Size(pEnd_out.X- pStart_out.X, pEnd_out.Y - pStart_out.Y));

                if (isSettingRect_1)
                {
                    rectArray[0] = rect_pic;
                }
                if (isSettingRect_2)
                {
                    rectArray[1] = rect_pic;
                }
            }

            #region 测试
            //Point p1, p2;
            //Size panelSize, picSize;
            //p1 = e.Location;
            //panelSize = setTarget_pb.Size;
            //picSize = this.picSize;
            //transPositToPic(in p1,panelSize,picSize,out p2);
            //MessageBox.Show(p2.ToString());
            #endregion
        }

        private void SetTargetForm_Load(object sender, EventArgs e)
        {
            this.SAVE_EVENT += showTargetPic;


        }

        private void showTargetPic(Image img, params Rectangle[] rectangles)
        {
            Image img1 = getTargetImg(img, rectangles[0]), img2 = getTargetImg(img, rectangles[1]);
            target1_pb.Invoke(new Action(() => {
                target1_pb.Image = img1;
            })); 
            target2_pb.Invoke(new Action(() => {
                target2_pb.Image = img2;
            }));
            if(!Directory.Exists("Setting"))
            {
                Directory.CreateDirectory("Setting");
            }
            img1.Save("Setting\\target1.jpg");
            img2.Save("Setting\\target2.jpg");
            img.Save("Setting\\template.jpg");
        }
        private Image getTargetImg(Image img,Rectangle rect)
        {
            Image img_out=new Bitmap(rect.Width,rect.Height);
            Rectangle detRect = new Rectangle(0,0,rect.Width,rect.Height);
            using (Graphics g=Graphics.FromImage(img_out))
            {
                g.DrawImage(img, detRect, rect,GraphicsUnit.Pixel);
            }
            return img_out;
        }

        private void setTargetArea_bt_Click(object sender, EventArgs e)
        {
            isSettingRect_1 = !isSettingRect_1;
            setTargetArea_bt.BackColor = isSettingRect_1 ?  Color.LightYellow:Color.FromArgb(255, 240, 240, 240);
            if(isSettingRect_1)
            {
                isSettingRect_2 = false; 
                setTarget2Area_bt.BackColor = isSettingRect_2 ? Color.LightYellow : Color.FromArgb(255, 240, 240, 240);
            }
            setTarget_pb.Invalidate();
        }

        private void setTarget_pb_Paint(object sender, PaintEventArgs e)
        {
            if(isRectDrawing)
            {
                Pen p = new Pen(Color.Black);
                if (isSettingRect_1)
                {
                    p = new Pen(Color.Red, 3.0f);
                }
                if (isSettingRect_2)
                {
                    p = new Pen(Color.Green, 3.0f);
                }
                e.Graphics.DrawRectangle(p, rect);
            }
        }

        private void setTarget2Area_bt_Click(object sender, EventArgs e)
        {
            isSettingRect_2 = !isSettingRect_2;
            setTarget2Area_bt.BackColor = isSettingRect_2 ? Color.LightYellow : Color.FromArgb(255, 240, 240, 240);
            if (isSettingRect_2)
            {
                isSettingRect_1 = false;
                setTargetArea_bt.BackColor = isSettingRect_1 ? Color.LightYellow : Color.FromArgb(255, 240, 240, 240);
            }
            setTarget_pb.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
        }

        private void save_bt_Click(object sender, EventArgs e)
        {
            if((rectArray[0] == null) |(rectArray[1] == null))
            {
                MessageBox.Show("rect null");
            }
            else if(SAVE_EVENT!=null)
            {
                SAVE_EVENT(this.img, rectArray[0], rectArray[1]);
            }
        }

        private void deepCopy(in Rectangle rectIn,out Rectangle rectOut)
        {
            rectOut = new Rectangle(rectIn.X,rectIn.Y,rectIn.Width,rectIn.Height);
        }
        /// <summary>
        /// 相对于容器控件的坐标转为图片像素坐标
        /// </summary>
        /// <param name="p_in">输入坐标</param>
        /// <param name="panelSize">图片容器尺寸</param>
        /// <param name="picSize">图片尺寸</param>
        /// <param name="p_out">输出坐标</param>
        private void transPositToPic(in Point p_in,in Size panelSize,in Size picSize,out Point p_out)
        {
            p_out = new Point(0,0);
            float zoomProportion = 1.0f;//原图尺寸÷显示图尺寸
            //float zoomWidth = 1.0f, zoomHeight = 1.0f;//原图尺寸÷panel尺寸
            //如果窗体宽高比 大于 图像宽高比，缩放后的图像高度=容器高度
            if (((float)(panelSize.Width)/panelSize.Height) >((float)(picSize.Width)/picSize.Height))
            {
                zoomProportion = (float)picSize.Height / panelSize.Height;
                //a：原图宽度；b:panel宽度；z:图片zoom参数；
                //c:显示图片宽度 c=a/z
                //x:输入坐标x
                //输出坐标：X=(x-(b-c)/2)*z
                p_out.X = (int)((p_in.X - (panelSize.Width - (picSize.Width / zoomProportion)) / 2) * zoomProportion);
                p_out.Y = (int)(p_in.Y * zoomProportion);
            }
            else
            {
                zoomProportion = (float)picSize.Width / panelSize.Width;
                p_out.X = (int)(p_in.X * zoomProportion);
                //a：原图高度；b:panel高度；z:图片zoom参数；
                //c:显示图片高度 c=a/z
                //y:输入坐标x
                //输出坐标：Y=(y-(b-c)/2)*z
                p_out.Y = (int)((p_in.Y - (panelSize.Height - (picSize.Height / zoomProportion)) / 2) * zoomProportion);
            }
        }
    }
}
